using System;
using System.Collections.Generic;

namespace MEA.AE_Data.Config
{
	public abstract class ConfigKWP
	{
		public enum e_CanMsg
		{
			Receive,
			Send,
			Count
		}

		public enum e_DiagModes
		{
			Diagnostic,
			Flash,
			LiveView,
			MemoryAccess,
			Count
		}

		public enum e_kwpServices : byte
		{
			Communication_Start,
			Communication_Stop,
			DatLog_Config_Write,
			DatLog_Config_Read,
			Diagnostic_Start,
			Diagnostic_Stop,
			DTC_Clear,
			DTC_Detail,
			DTC_List,
			DTC_On,
			DTC_Off,
			ECU_Coding_Write,
			ECU_Serial_Read,
			ECU_SWVersion,
			ECU_Reset,
			ECU_TimingParameterAccess,
			Engine_Serial_Read,
			Engine_Serial_Write,
			Engine_Uptime_Read,
			Engine_Uptime_Reset,
			Flash_DataWriteByLID,
			Flash_DataReadByLID,
			Flash_RequestDownload,
			Flash_RequestResChkSum,
			Flash_RequestResErase,
			Flash_StartChecksumCalculation,
			Flash_StartFlashErase,
			Flash_StopRoutine,
			Flash_TransferData,
			Flash_TransferExit,
			Format_DatLogEvRec_1,
			Format_DatLogEvRec_2_1,
			Format_DatLogEvRec_2_2,
			LID_Data_Write,
			LiveView_Config_Clear,
			LiveView_Config_Write,
			LiveView_Sample_Read,
			IQA_Init_1,
			IQA_Init_2,
			IQA_ReadCylinder,
			IQA_WriteCylinder,
			IQA_CylinderSID,
			RecManStatus_Read,
			RecManSector_Read,
			RTC_Read,
			RTC_Write,
			Statistics_Read,
			Statistics_Reset,
			Tester_Present,
			SecuritySeedKey,
			RailPresureControlValveStart,
			HighPressureStart,
			RunUpStart,
			ShutOffStart,
			RailPresureControlValveStop,
			HighPressureStop,
			RunUpStop,
			ShutOffStop,
			ReadTable_6C,
			ReadTable_68,
			ReadTable_69,
			ReadTable_64,
			ReadTable_65,
			Count
		}

		private const int standardWaitForResponse = 3000;

		private static byte[] diagModes;

		private static List<ushort> canMsgIDs_A;

		private static List<ushort> canMsgIDs_B;

		private static List<List<byte>> sendLists;

		private static byte negativeResponse;

		private static int[] responseTimeList;

		private static uint[,] uKey_DiagMask_cu8;

		private static uint[,] uKey_FlashMask_cu8;

		public static byte NegativeResponse
		{
			get
			{
				return negativeResponse;
			}
		}

		public static uint[,] UKey_DiagMask_cu8
		{
			get
			{
				return uKey_DiagMask_cu8;
			}
		}

		public static uint[,] UKey_FlashMask_cu8
		{
			get
			{
				return uKey_FlashMask_cu8;
			}
		}

		public static byte PositiveResponse(e_kwpServices sid)
		{
			return (byte)(sendLists[(int)sid][0] + 64);
		}

		public static List<byte> SendList(e_kwpServices sid)
		{
			return sendLists[(int)sid];
		}

		public static int ResponseTime(e_kwpServices sid)
		{
			return responseTimeList[(uint)sid];
		}

		private static void InitSendLists()
		{
			sendLists = new List<List<byte>>(63);
			for (int i = 0; i < sendLists.Capacity; i++)
			{
				sendLists.Add(new List<byte>());
			}
			sendLists[0] = new List<byte>(new byte[1] { 129 });
			sendLists[1] = new List<byte>(new byte[1] { 130 });
			sendLists[2] = new List<byte>(new byte[35]
			{
				59, 242, 10, 3, 32, 3, 33, 3, 34, 3,
				35, 3, 36, 3, 37, 3, 38, 3, 39, 3,
				40, 3, 41, 3, 42, 3, 43, 3, 44, 3,
				45, 3, 46, 3, 47
			});
			sendLists[3] = new List<byte>(new byte[2] { 33, 242 });
			sendLists[4] = new List<byte>(new byte[1] { 16 });
			sendLists[5] = new List<byte>(new byte[1] { 32 });
			sendLists[6] = new List<byte>(new byte[3] { 20, 255, 0 });
			sendLists[7] = new List<byte>(new byte[1] { 23 });
			sendLists[8] = new List<byte>(new byte[4] { 24, 2, 255, 0 });
			sendLists[9] = new List<byte>(new byte[5] { 133, 1, 255, 0, 1 });
			sendLists[10] = new List<byte>(new byte[5] { 133, 1, 255, 0, 2 });
			sendLists[11] = new List<byte>(new byte[11]
			{
				59, 2, 129, 0, 97, 8, 8, 0, 97, 56,
				137
			});
			sendLists[12] = new List<byte>(new byte[2] { 26, 134 });
			sendLists[13] = new List<byte>(new byte[2] { 26, 147 });
			sendLists[14] = new List<byte>(new byte[2] { 17, 1 });
			sendLists[15] = new List<byte>(new byte[2] { 131, 3 });
			sendLists[17] = new List<byte>(new byte[2] { 59, 150 });
			sendLists[16] = new List<byte>(new byte[2] { 26, 150 });
			sendLists[18] = new List<byte>(new byte[2] { 33, 245 });
			sendLists[19] = new List<byte>(new byte[2] { 59, 245 });
			sendLists[20] = new List<byte>(new byte[3] { 59, 155, 2 });
			sendLists[21] = new List<byte>(new byte[2] { 26, 155 });
			sendLists[22] = new List<byte>(new byte[1] { 52 });
			sendLists[23] = new List<byte>(new byte[2] { 51, 1 });
			sendLists[24] = new List<byte>(new byte[2] { 51, 2 });
			sendLists[25] = new List<byte>(new byte[2] { 49, 1 });
			sendLists[26] = new List<byte>(new byte[2] { 49, 2 });
			sendLists[27] = new List<byte>(new byte[2] { 50, 1 });
			sendLists[28] = new List<byte>(new byte[1] { 54 });
			sendLists[29] = new List<byte>(new byte[1] { 55 });
			sendLists[30] = new List<byte>(new byte[2] { 49, 3 });
			sendLists[31] = new List<byte>(new byte[10] { 59, 3, 16, 1, 255, 252, 170, 170, 170, 170 });
			sendLists[32] = new List<byte>(new byte[10] { 59, 3, 16, 0, 31, 252, 170, 170, 170, 170 });
			sendLists[37] = new List<byte>(new byte[2] { 33, 2 });
			sendLists[38] = new List<byte>(new byte[23]
			{
				48, 72, 8, 0, 0, 0, 16, 0, 0, 0,
				0, 16, 0, 0, 0, 0, 16, 0, 0, 0,
				0, 16, 0
			});
			sendLists[39] = new List<byte>(new byte[1] { 48 });
			sendLists[40] = new List<byte>(new byte[1] { 48 });
			sendLists[33] = new List<byte>(new byte[2] { 59, 244 });
			sendLists[34] = new List<byte>(new byte[3] { 44, 240, 4 });
			sendLists[35] = new List<byte>(new byte[2] { 44, 240 });
			sendLists[36] = new List<byte>(new byte[2] { 33, 240 });
			sendLists[42] = new List<byte>(new byte[2] { 33, 243 });
			sendLists[43] = new List<byte>(new byte[2] { 33, 246 });
			sendLists[44] = new List<byte>(new byte[2] { 33, 241 });
			sendLists[45] = new List<byte>(new byte[2] { 59, 241 });
			sendLists[46] = new List<byte>(new byte[2] { 33, 244 });
			sendLists[47] = new List<byte>(new byte[10] { 59, 244, 0, 0, 0, 0, 0, 0, 0, 0 });
			sendLists[48] = new List<byte>(new byte[2] { 62, 1 });
			sendLists[49] = new List<byte>(new byte[1] { 39 });
			sendLists[50] = new List<byte>(new byte[2] { 49, 41 });
			sendLists[51] = new List<byte>(new byte[3] { 49, 42, 0 });
			sendLists[52] = new List<byte>(new byte[3] { 49, 43, 0 });
			sendLists[53] = new List<byte>(new byte[2] { 49, 44 });
			sendLists[54] = new List<byte>(new byte[2] { 50, 41 });
			sendLists[55] = new List<byte>(new byte[2] { 50, 42 });
			sendLists[56] = new List<byte>(new byte[2] { 50, 43 });
			sendLists[57] = new List<byte>(new byte[2] { 50, 44 });
			sendLists[58] = new List<byte>(new byte[2] { 33, 108 });
			sendLists[59] = new List<byte>(new byte[2] { 33, 104 });
			sendLists[60] = new List<byte>(new byte[2] { 33, 105 });
			sendLists[61] = new List<byte>(new byte[2] { 33, 100 });
			sendLists[62] = new List<byte>(new byte[2] { 33, 101 });
		}

		private static void InitResponseTimes()
		{
			responseTimeList = new int[63];
			for (int i = 0; i < responseTimeList.Length; i++)
			{
				responseTimeList[i] = 3000;
			}
			responseTimeList[0] = 3000;
			responseTimeList[1] = 3000;
			responseTimeList[2] = 3000;
			responseTimeList[3] = 3000;
			responseTimeList[4] = 3000;
			responseTimeList[5] = 3000;
			responseTimeList[6] = 3000;
			responseTimeList[7] = 3000;
			responseTimeList[8] = 3000;
			responseTimeList[9] = 3000;
			responseTimeList[10] = 3000;
			responseTimeList[11] = 3000;
			responseTimeList[12] = 3000;
			responseTimeList[13] = 3000;
			responseTimeList[14] = 3000;
			responseTimeList[15] = 3000;
			responseTimeList[16] = 3000;
			responseTimeList[17] = 3000;
			responseTimeList[18] = 3000;
			responseTimeList[19] = 3000;
			responseTimeList[20] = 3000;
			responseTimeList[21] = 3000;
			responseTimeList[22] = 6000;
			responseTimeList[23] = 8000;
			responseTimeList[24] = 8000;
			responseTimeList[25] = 8000;
			responseTimeList[26] = 20000;
			responseTimeList[27] = 6000;
			responseTimeList[28] = 10000;
			responseTimeList[29] = 3000;
			responseTimeList[30] = 120000;
			responseTimeList[31] = 3000;
			responseTimeList[32] = 3000;
			responseTimeList[37] = 3000;
			responseTimeList[38] = 3000;
			responseTimeList[41] = 3000;
			responseTimeList[39] = 3000;
			responseTimeList[40] = 3000;
			responseTimeList[33] = 3000;
			responseTimeList[34] = 10000;
			responseTimeList[35] = 10000;
			responseTimeList[36] = 10000;
			responseTimeList[42] = 3000;
			responseTimeList[43] = 25000;
			responseTimeList[44] = 3000;
			responseTimeList[45] = 3000;
			responseTimeList[46] = 3000;
			responseTimeList[47] = 3000;
			responseTimeList[48] = 3000;
			responseTimeList[49] = 3000;
			responseTimeList[50] = 3000;
			responseTimeList[51] = 3000;
			responseTimeList[52] = 3000;
			responseTimeList[53] = 3000;
			responseTimeList[54] = 3000;
			responseTimeList[55] = 3000;
			responseTimeList[56] = 3000;
			responseTimeList[57] = 3000;
			responseTimeList[58] = 3000;
			responseTimeList[59] = 3000;
			responseTimeList[60] = 3000;
			responseTimeList[61] = 3000;
			responseTimeList[62] = 3000;
		}

		private static void InitDiagModes()
		{
			diagModes = new byte[4];
			diagModes[0] = 132;
			diagModes[1] = 133;
			diagModes[2] = 134;
			diagModes[3] = 131;
		}

		public static void CanMsgIDs_Set(ConfigData.e_ECUID ecuID, ushort recID, ushort sendID)
		{
			switch (ecuID)
			{
			case ConfigData.e_ECUID.A:
			{
				canMsgIDs_A = new List<ushort>(2);
				for (int j = 0; j < canMsgIDs_A.Capacity; j++)
				{
					canMsgIDs_A.Add(0);
				}
				canMsgIDs_A[0] = recID;
				canMsgIDs_A[1] = sendID;
				break;
			}
			case ConfigData.e_ECUID.B:
			{
				canMsgIDs_B = new List<ushort>(2);
				for (int i = 0; i < canMsgIDs_B.Capacity; i++)
				{
					canMsgIDs_B.Add(0);
				}
				canMsgIDs_B[0] = recID;
				canMsgIDs_B[1] = sendID;
				break;
			}
			}
		}

		public static ushort CanMsgIDs_Get(ConfigData.e_ECUID ecuID, e_CanMsg msgID)
		{
			switch (ecuID)
			{
			case ConfigData.e_ECUID.A:
				return canMsgIDs_A[(int)msgID];
			case ConfigData.e_ECUID.B:
				return canMsgIDs_B[(int)msgID];
			default:
				throw new Exception("ConfigKWP: No valid ecu specified");
			}
		}

		public static byte DiagMode_Get(e_DiagModes mode)
		{
			return diagModes[(int)mode];
		}

		public static byte DiagMode_Set(e_DiagModes mode, byte value)
		{
			return diagModes[(int)mode] = value;
		}

		static ConfigKWP()
		{
			negativeResponse = 127;
			uKey_DiagMask_cu8 = new uint[8, 4]
			{
				{ 61u, 73u, 214u, 141u },
				{ 3u, 194u, 79u, 186u },
				{ 244u, 203u, 228u, 45u },
				{ 68u, 21u, 145u, 191u },
				{ 207u, 222u, 173u, 252u },
				{ 199u, 108u, 224u, 14u },
				{ 211u, 205u, 114u, 121u },
				{ 111u, 152u, 109u, 172u }
			};
			uKey_FlashMask_cu8 = new uint[8, 4]
			{
				{ 208u, 220u, 67u, 218u },
				{ 99u, 157u, 104u, 34u },
				{ 147u, 153u, 232u, 130u },
				{ 17u, 127u, 85u, 33u },
				{ 198u, 237u, 162u, 180u },
				{ 222u, 111u, 253u, 64u },
				{ 155u, 79u, 142u, 248u },
				{ 175u, 26u, 217u, 140u }
			};
			InitDiagModes();
			InitResponseTimes();
			InitSendLists();
			CanMsgIDs_Set(ConfigData.e_ECUID.A, 2024, 2016);
			CanMsgIDs_Set(ConfigData.e_ECUID.B, 2025, 2017);
		}

		public static string StatusToString(string stat)
		{
			short num = Convert.ToInt16(stat, 2);
			short num2 = 0;
			num2 = num;
			string text = "";
			short num3 = num2;
			num3 &= 0x60;
			for (int i = 0; i < 8; i++)
			{
				switch ((ConfigData.ECombinedEngineStatus)(byte)i)
				{
				case ConfigData.ECombinedEngineStatus.eEStatAfterRun:
				case ConfigData.ECombinedEngineStatus.eEStatStart:
				case ConfigData.ECombinedEngineStatus.eEStatNormal:
				case ConfigData.ECombinedEngineStatus.eEStatRailPres:
				case ConfigData.ECombinedEngineStatus.eEStatAirOnGrd:
					text = (((num2 & 1) != 1) ? (text + "No       - ") : (text + "Yes      - "));
					text += ConfigData.SCombinedEngineStatus[i];
					break;
				case ConfigData.ECombinedEngineStatus.eEStatProposedAct:
				case ConfigData.ECombinedEngineStatus.eEStatVoterDecis:
					text = (((num2 & 1) != 1) ? (text + "ECU A - ") : (text + "ECU B - "));
					text += ConfigData.SCombinedEngineStatus[i];
					break;
				case ConfigData.ECombinedEngineStatus.eEStatEEActiv:
					text = (((num2 & 1) != 1) ? (text + "ECU is active") : (text + "ECU is passive"));
					switch (num3)
					{
					case 32:
						text += "\nthe pilot has overruled the voter and manually selected ECU-A to become active";
						break;
					case 64:
						text += "\nthe pilot has overruled the voter and manually selected ECU-B to become active";
						break;
					}
					break;
				}
				num2 >>= 1;
			}
			return text;
		}
	}
}
